// @Author : zaniu(zzaniu@126.com)
// @Time   : 2021/9/1 11:14
// @Desc   :
//
//                   _ooOoo_
//                  o8888888o
//                  88" . "88
//                  (| -_- |)
//                  O\  =  /O
//               ____/`---'\____
//             .'  \\|     |//  `.
//            /  \\|||  :  |||//  \
//           /  _||||| -:- |||||-  \
//           |   | \\\  -  /// |   |
//           | \_|  ''\---/''  |   |
//           \  .-\__  `-`  ___/-. /
//         ___`. .'  /--.--\  `. . __
//      ."" '<  `.___\_<|>_/___.'  >'"".
//     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//     \  \ `-.   \_ __\ /__ _/   .-` /  /
// =====`-.____`-.___\_____/___.-`____.-'=====
//                   `=---='
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//           佛祖保佑       永无BUG
//
package client

import (
	"context"
	"distributedTransaction/proto2go"
	"errors"
	"fmt"
	"github.com/apache/rocketmq-client-go/v2"
	"google.golang.org/grpc"
	"strconv"
	"time"
)

func generateNo() string {
	// 这个肯定是不行的啊，这个只能演示用，这个高并发的情况下是没法保证唯一的
	return strconv.Itoa(int(time.Now().UnixNano()))
}

func detainInventory(grpcConn *grpc.ClientConn, globalNo string, userName string, goodsName string, goodsNumber uint64) error {
	inventoryClient := proto2go.NewInventoryClient(grpcConn)
	ctx := context.Background()
	inventoryInfo := &proto2go.InventoryRequest{GlobalNo: globalNo, UserName: userName, GoodsName: goodsName, GoodsNumber: goodsNumber}
	inventoryRet, err := inventoryClient.DetainInventory(ctx, inventoryInfo)
	if err != nil {
		fmt.Println("RPC调用失败。 err = ", err.Error())
		return err
	}
	if !inventoryRet.Flag {
		fmt.Println("库存扣减失败，可能是库存不足。 err = ", inventoryRet.ErrorMessage)
		return errors.New(inventoryRet.ErrorMessage)
	}
	return nil
}

func CreateOrder(grpcConn *grpc.ClientConn, globalNo string, userName string, goodsName string, goodsNumber uint64) error {
	orderClient := proto2go.NewOrderClient(grpcConn)
	ctx := context.Background()
	orderInfo := &proto2go.OrderRequest{GlobalNo: globalNo, UserName: userName, GoodsName: goodsName, GoodsNumber: goodsNumber}
	inventoryRet, err := orderClient.CreateOrder(ctx, orderInfo)
	if err != nil {
		fmt.Println("RPC调用失败。 err = ", err.Error())
		return err
	}
	if !inventoryRet.Flag {
		fmt.Println("创建订单失败。 err = ", inventoryRet.ErrorMessage)
		return errors.New(inventoryRet.ErrorMessage)
	}
	return nil
}

func PlaceOrder(p *rocketmq.TransactionProducer, userName, goodsName string, goodsNumber uint64) (string, error) {
	// 生成一个全局唯一的流水号
	globalNo := generateNo()
	err := SendTransactionMessage(p, globalNo, userName, goodsName, goodsNumber)
	if err != nil {
		return "", err
	}

	return globalNo, nil
}
